/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gp.vlc.rp.gui;

import com.googlecode.sardine.DavResource;
import com.googlecode.sardine.impl.SardineImpl;
import gp.vlc.rp.net.MyFactory;
import gp.vlc.rp.net.ReverseProxyConfiguration;
import gp.vlc.rp.net.ReverseProxyServerSocket;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Namo
 */
public class JFrame extends javax.swing.JFrame {

    private Logger _logger = LoggerFactory.getLogger(this.getClass());
    private URI _vlc;
    private WebDAVScanner _webDAVScanner;
    private URI _lastScanUri;
    private DefaultListModel _fullDefaultListModel;
    private DefaultListModel _filteredDefaultListModel;

    /**
     * Creates new form JFrame
     */
    public JFrame() {
        JDialogException.defaultParent = this;
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) {
            new JDialogException(e).setVisible(true);
        }

        initComponents();

        _vlc = null;
        _webDAVScanner = null;
        ArrayList<URI> defaultPlaces = new ArrayList<URI>();

        try {
            defaultPlaces.add(new URI("file:/C:/Program%20Files/VideoLAN/VLC/vlc.exe"));
            defaultPlaces.add(new URI("file:/C:/Program%20Files%20(x86)/VideoLAN/VLC/vlc.exe"));
        }
        catch (URISyntaxException e) {
            new JDialogException(e).setVisible(true);
        }

        // try to find a default location
        for (URI uri : defaultPlaces) {
            File file = new File(uri);
            if (file.exists()) {
                _logger.info(file.getAbsolutePath() + " exists");
                _vlc = uri;
            }
            else {
                _logger.info(file.getAbsolutePath() + " does not exists");
            }
        }

        jPanelButtonWebDAV.setText("WebDAV browser");
        jPanelButtonGeneral.setText("General settings");
        jPanelButtonProxy.setText("Proxy settings");

        jListWebDAVResources.setCellRenderer(new DefaultListCellRenderer() {
            @Override
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                URI uri= (URI) value;
                if(null != _lastScanUri){
                    uri = _lastScanUri.relativize(uri);
                }
                
                return super.getListCellRendererComponent(list, uri.getPath(), index, isSelected, cellHasFocus);
            }
        });

        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    jPanelGeneral.setVisible(false);
                    jPanelProxy.setVisible(false);
                    jPanelWebDAV.setVisible(false);
                    jButtonWebDAVStop.setVisible(false);
                    revalidate();
                    pack();
                }
            });
        }
        catch (Exception e) {
            new JDialogException(e).setVisible(true);
        }

        displayURI(_vlc);

        _fullDefaultListModel = new DefaultListModel();
        _filteredDefaultListModel = new DefaultListModel();
        jListWebDAVResources.setModel(_filteredDefaultListModel);

        _fullDefaultListModel.addListDataListener(new ListDataListener() {
            public void intervalAdded(ListDataEvent e) {
                URI uri = (URI) _fullDefaultListModel.getElementAt(e.getIndex0());
                synchronized (_filteredDefaultListModel) {
                    if (matchesFilter(uri)) {
                        _filteredDefaultListModel.addElement(uri);
                    }
                }
            }

            public void intervalRemoved(ListDataEvent e) {
            }

            public void contentsChanged(ListDataEvent e) {
            }
        });

        jTextFieldWebDAVFilter.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                update();
            }

            public void removeUpdate(DocumentEvent e) {
                update();
            }

            public void insertUpdate(DocumentEvent e) {
                update();
            }

            public void update() {
                synchronized (_filteredDefaultListModel) {
                    _filteredDefaultListModel.clear();
                    int size = _fullDefaultListModel.size();
                    for (int i = 0; i < size; i++) {
                        URI uri = (URI) _fullDefaultListModel.getElementAt(i);
                        if (matchesFilter(uri)) {
                            _filteredDefaultListModel.addElement(uri);
                        }
                    }
                }
            }
        });
    }

    private boolean matchesFilter(URI uri) {
        String[] words = jTextFieldWebDAVFilter.getText().split(" ");
        String path = uri.getPath();
        for (String word : words) {
            if (!word.trim().isEmpty() && !path.toLowerCase().contains(word.trim().toLowerCase())) {
                return false;
            }
        }
        return true;
    }

    private void displayURI(URI uri) {
        if (null != uri) {
            jTextFieldVLC.setText(new File(uri).getAbsolutePath());
            jButtonPlay.setEnabled(true);
        }
        else {
            jTextFieldVLC.setText("Unknown");
            jButtonPlay.setEnabled(false);
        }
    }

    private ReverseProxyConfiguration getConfig(URI uri) throws URISyntaxException {
        ReverseProxyConfiguration config = new ReverseProxyConfiguration(uri);
        config.setCredentials(new UsernamePasswordCredentials(jTextFieldUsername.getText().trim(), new String(jPasswordPassword.getPassword())));
        config.setProxyCredentials(new UsernamePasswordCredentials(_jTextFieldProxyUsername.getText().trim(), new String(_jPasswordProxyPassword.getPassword())));
        config.setProxyHost(jTextFieldProxyHost.getText().trim());
        config.setProxyPort(Integer.parseInt(jTextFieldProxyPort.getText().trim()));
        return config;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel4 = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jTextFieldURL = new javax.swing.JTextField();
        jButtonPlay = new javax.swing.JButton();
        jPanelButtonWebDAV = new gp.vlc.rp.gui.JPanelButton();
        jPanelWebDAV = new javax.swing.JPanel();
        jTextFieldWebDAVURL = new javax.swing.JTextField();
        jButtonWebDAVScan = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jScrollPaneWebDAVResources = new javax.swing.JScrollPane();
        jListWebDAVResources = new javax.swing.JList();
        jLabel12 = new javax.swing.JLabel();
        jTextFieldWebDAVFilter = new javax.swing.JTextField();
        jButtonWebDAVStop = new javax.swing.JButton();
        filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 10), new java.awt.Dimension(10, 10), new java.awt.Dimension(32767, 0));
        filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6));
        jPanelButtonGeneral = new gp.vlc.rp.gui.JPanelButton();
        jPanelGeneral = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        jTextFieldVLC = new javax.swing.JTextField();
        jButtonBrowse = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        jTextFieldUsername = new javax.swing.JTextField();
        jPasswordPassword = new javax.swing.JPasswordField();
        jLabel3 = new javax.swing.JLabel();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6));
        jPanelButtonProxy = new gp.vlc.rp.gui.JPanelButton();
        jPanelProxy = new javax.swing.JPanel();
        jLabel10 = new javax.swing.JLabel();
        jTextFieldProxyHost = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        jTextFieldProxyPort = new javax.swing.JTextField();
        _jTextFieldProxyUsername = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        _jPasswordProxyPassword = new javax.swing.JPasswordField();
        jLabel9 = new javax.swing.JLabel();
        filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6));
        filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6), new java.awt.Dimension(6, 6));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("VLC Workaround");
        setBackground(new java.awt.Color(255, 255, 255));
        setLocationByPlatform(true);
        setResizable(false);

        jPanel4.setBackground(new java.awt.Color(255, 255, 255));
        jPanel4.setOpaque(false);

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(160, 160, 160)));

        jTextFieldURL.setBackground(new java.awt.Color(229, 255, 229));
        jTextFieldURL.setText("https://www.myhost.com.com/path/to/video.avi");
        jTextFieldURL.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldURLFocusGained(evt);
            }
        });
        jTextFieldURL.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextFieldURLKeyPressed(evt);
            }
        });

        jButtonPlay.setText("Play");
        jButtonPlay.setEnabled(false);
        jButtonPlay.setFocusPainted(false);
        jButtonPlay.setMaximumSize(new java.awt.Dimension(60, 22));
        jButtonPlay.setMinimumSize(new java.awt.Dimension(60, 22));
        jButtonPlay.setOpaque(false);
        jButtonPlay.setPreferredSize(new java.awt.Dimension(60, 22));
        jButtonPlay.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonPlayActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextFieldURL, javax.swing.GroupLayout.PREFERRED_SIZE, 462, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldURL, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonPlay, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        jPanelButtonWebDAV.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(160, 160, 160)));
        jPanelButtonWebDAV.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jPanelButtonWebDAVMousePressed(evt);
            }
        });
        jPanelButtonWebDAV.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jPanelButtonWebDAVKeyTyped(evt);
            }
        });

        jPanelWebDAV.setBackground(new java.awt.Color(255, 255, 255));
        jPanelWebDAV.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 1, 1, 1, new java.awt.Color(160, 160, 160)));
        jPanelWebDAV.setPreferredSize(new java.awt.Dimension(400, 191));

        jTextFieldWebDAVURL.setText("https://www.host.com/webdav/");
        jTextFieldWebDAVURL.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldWebDAVURLFocusGained(evt);
            }
        });

        jButtonWebDAVScan.setText("Scan");
        jButtonWebDAVScan.setFocusPainted(false);
        jButtonWebDAVScan.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonWebDAVScanActionPerformed(evt);
            }
        });

        jLabel1.setText("WebDAV URL :");

        jListWebDAVResources.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jListWebDAVResources.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jListWebDAVResourcesMouseClicked(evt);
            }
        });
        jListWebDAVResources.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListWebDAVResourcesValueChanged(evt);
            }
        });
        jScrollPaneWebDAVResources.setViewportView(jListWebDAVResources);

        jLabel12.setText("Filter :");

        jTextFieldWebDAVFilter.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldWebDAVFilterFocusGained(evt);
            }
        });

        jButtonWebDAVStop.setText("Stop");
        jButtonWebDAVStop.setFocusPainted(false);
        jButtonWebDAVStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonWebDAVStopActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelWebDAVLayout = new javax.swing.GroupLayout(jPanelWebDAV);
        jPanelWebDAV.setLayout(jPanelWebDAVLayout);
        jPanelWebDAVLayout.setHorizontalGroup(
            jPanelWebDAVLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelWebDAVLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelWebDAVLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPaneWebDAVResources)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelWebDAVLayout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(jLabel12)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jTextFieldWebDAVFilter, javax.swing.GroupLayout.PREFERRED_SIZE, 498, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelWebDAVLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextFieldWebDAVURL)
                        .addGap(0, 0, 0)
                        .addComponent(filler5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, 0)
                        .addComponent(jButtonWebDAVScan)
                        .addGap(0, 0, 0)
                        .addComponent(jButtonWebDAVStop)))
                .addComponent(filler4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0))
        );
        jPanelWebDAVLayout.setVerticalGroup(
            jPanelWebDAVLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelWebDAVLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelWebDAVLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelWebDAVLayout.createSequentialGroup()
                        .addGroup(jPanelWebDAVLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jTextFieldWebDAVURL, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButtonWebDAVScan)
                            .addComponent(jLabel1)
                            .addComponent(jButtonWebDAVStop)
                            .addComponent(filler5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jScrollPaneWebDAVResources, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanelWebDAVLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jTextFieldWebDAVFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel12)))
                    .addComponent(filler4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        jPanelButtonGeneral.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(160, 160, 160)));
        jPanelButtonGeneral.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jPanelButtonGeneralMousePressed(evt);
            }
        });
        jPanelButtonGeneral.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jPanelButtonGeneralKeyTyped(evt);
            }
        });

        jPanelGeneral.setBackground(new java.awt.Color(255, 255, 255));
        jPanelGeneral.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 1, 1, 1, new java.awt.Color(160, 160, 160)));

        jLabel5.setText("VLC path :");

        jTextFieldVLC.setEditable(false);
        jTextFieldVLC.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldVLCFocusGained(evt);
            }
        });

        jButtonBrowse.setText("Browse");
        jButtonBrowse.setFocusPainted(false);
        jButtonBrowse.setMaximumSize(new java.awt.Dimension(60, 22));
        jButtonBrowse.setMinimumSize(new java.awt.Dimension(60, 22));
        jButtonBrowse.setPreferredSize(new java.awt.Dimension(60, 22));
        jButtonBrowse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonBrowseActionPerformed(evt);
            }
        });

        jLabel2.setText("Username :");

        jTextFieldUsername.setText("username");
        jTextFieldUsername.setMinimumSize(new java.awt.Dimension(100, 20));
        jTextFieldUsername.setPreferredSize(new java.awt.Dimension(100, 20));
        jTextFieldUsername.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldUsernameFocusGained(evt);
            }
        });
        jTextFieldUsername.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextFieldUsernameKeyPressed(evt);
            }
        });

        jPasswordPassword.setText("password");
        jPasswordPassword.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jPasswordPasswordFocusGained(evt);
            }
        });
        jPasswordPassword.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jPasswordPasswordKeyPressed(evt);
            }
        });

        jLabel3.setText("Password :");

        javax.swing.GroupLayout jPanelGeneralLayout = new javax.swing.GroupLayout(jPanelGeneral);
        jPanelGeneral.setLayout(jPanelGeneralLayout);
        jPanelGeneralLayout.setHorizontalGroup(
            jPanelGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelGeneralLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 61, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelGeneralLayout.createSequentialGroup()
                        .addComponent(jTextFieldVLC)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonBrowse, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanelGeneralLayout.createSequentialGroup()
                        .addComponent(jTextFieldUsername, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jPasswordPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        jPanelGeneralLayout.setVerticalGroup(
            jPanelGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelGeneralLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jTextFieldUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPasswordPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelGeneralLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldVLC, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonBrowse, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanelButtonProxy.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(160, 160, 160)));
        jPanelButtonProxy.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jPanelButtonProxyMousePressed(evt);
            }
        });
        jPanelButtonProxy.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jPanelButtonProxyKeyTyped(evt);
            }
        });

        jPanelProxy.setBackground(new java.awt.Color(255, 255, 255));
        jPanelProxy.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 1, 1, 1, new java.awt.Color(160, 160, 160)));
        jPanelProxy.setPreferredSize(new java.awt.Dimension(400, 69));

        jLabel10.setText("Host :");

        jTextFieldProxyHost.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldProxyHostFocusGained(evt);
            }
        });
        jTextFieldProxyHost.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextFieldProxyHostKeyPressed(evt);
            }
        });

        jLabel4.setText("Port :");

        jTextFieldProxyPort.setText("3128");
        jTextFieldProxyPort.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldProxyPortFocusGained(evt);
            }
        });
        jTextFieldProxyPort.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextFieldProxyPortKeyPressed(evt);
            }
        });

        _jTextFieldProxyUsername.setText("proxy_username");
        _jTextFieldProxyUsername.setMinimumSize(new java.awt.Dimension(100, 20));
        _jTextFieldProxyUsername.setPreferredSize(new java.awt.Dimension(100, 20));
        _jTextFieldProxyUsername.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                _jTextFieldProxyUsernameFocusGained(evt);
            }
        });
        _jTextFieldProxyUsername.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                _jTextFieldProxyUsernameKeyPressed(evt);
            }
        });

        jLabel6.setText("Username :");

        _jPasswordProxyPassword.setText("password");
        _jPasswordProxyPassword.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                _jPasswordProxyPasswordFocusGained(evt);
            }
        });
        _jPasswordProxyPassword.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                _jPasswordProxyPasswordKeyPressed(evt);
            }
        });

        jLabel9.setText("Password :");

        javax.swing.GroupLayout jPanelProxyLayout = new javax.swing.GroupLayout(jPanelProxy);
        jPanelProxy.setLayout(jPanelProxyLayout);
        jPanelProxyLayout.setHorizontalGroup(
            jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelProxyLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel10)
                    .addComponent(jLabel4))
                .addGap(18, 18, 18)
                .addGroup(jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTextFieldProxyHost, javax.swing.GroupLayout.PREFERRED_SIZE, 185, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldProxyPort, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel6)
                    .addComponent(jLabel9))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(_jTextFieldProxyUsername, javax.swing.GroupLayout.DEFAULT_SIZE, 137, Short.MAX_VALUE)
                    .addComponent(_jPasswordProxyPassword))
                .addContainerGap())
        );
        jPanelProxyLayout.setVerticalGroup(
            jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelProxyLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel10)
                    .addComponent(jTextFieldProxyHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(_jTextFieldProxyUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldProxyPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4)
                    .addComponent(_jPasswordProxyPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(filler2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(filler1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanelProxy, javax.swing.GroupLayout.DEFAULT_SIZE, 561, Short.MAX_VALUE)
                    .addComponent(jPanelButtonProxy, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanelGeneral, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanelButtonGeneral, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanelButtonWebDAV, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanelWebDAV, javax.swing.GroupLayout.DEFAULT_SIZE, 561, Short.MAX_VALUE)
                    .addComponent(filler3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(6, 6, 6))
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanelButtonWebDAV, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(jPanelWebDAV, javax.swing.GroupLayout.DEFAULT_SIZE, 241, Short.MAX_VALUE)
                .addGap(0, 0, 0)
                .addComponent(filler3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(jPanelButtonGeneral, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(jPanelGeneral, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(jPanelButtonProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(jPanelProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(filler2, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPlayActionPerformed
        try {
            ReverseProxyConfiguration config = getConfig(new URI(jTextFieldURL.getText().trim()));
            final ReverseProxyServerSocket server = new ReverseProxyServerSocket(config);
            server.start();
            Runtime runtime = Runtime.getRuntime();
            String vlcPath = new File(_vlc).getAbsolutePath();
            final Process process = runtime.exec("\"" + vlcPath + "\"" + " http://127.0.0.1:" + server.getLocalPort() + config.getURI().getPath());
            new Consumer(process.getErrorStream()).start();
            new Consumer(process.getInputStream()).start();

            // wait for VLC to end
            new Thread() {
                public void run() {
                    try {
                        process.waitFor();
                    }
                    catch (Exception e) {
                        _logger.error("error waiting for VLC process to end", e);
                    }

                    server.kill();
                }
            }.start();
        }
        catch (Exception e) {
            new JDialogException(e).setVisible(true);
        }
    }//GEN-LAST:event_jButtonPlayActionPerformed

    private void jButtonBrowseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonBrowseActionPerformed
        JFileChooser jFileChooser = new JFileChooser();
        int ret = jFileChooser.showOpenDialog(this);
        if (ret == JFileChooser.APPROVE_OPTION) {
            _vlc = jFileChooser.getSelectedFile().toURI();
        }

        displayURI(_vlc);
    }//GEN-LAST:event_jButtonBrowseActionPerformed

    private void jTextFieldURLFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldURLFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldURLFocusGained

    private void jTextFieldUsernameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldUsernameFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldUsernameFocusGained

    private void jPasswordPasswordFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jPasswordPasswordFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jPasswordPasswordFocusGained

    private void jTextFieldVLCFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldVLCFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldVLCFocusGained

    private void jTextFieldProxyHostFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldProxyHostFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldProxyHostFocusGained

    private void jTextFieldProxyPortFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldProxyPortFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldProxyPortFocusGained

    private void _jTextFieldProxyUsernameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event__jTextFieldProxyUsernameFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event__jTextFieldProxyUsernameFocusGained

    private void _jPasswordProxyPasswordFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event__jPasswordProxyPasswordFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event__jPasswordProxyPasswordFocusGained

    private void jTextFieldURLKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextFieldURLKeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            jButtonPlayActionPerformed(null);
        }
    }//GEN-LAST:event_jTextFieldURLKeyPressed

    private void jTextFieldUsernameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextFieldUsernameKeyPressed
        jTextFieldURLKeyPressed(evt);
    }//GEN-LAST:event_jTextFieldUsernameKeyPressed

    private void jPasswordPasswordKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jPasswordPasswordKeyPressed
        jTextFieldURLKeyPressed(evt);
    }//GEN-LAST:event_jPasswordPasswordKeyPressed

    private void jTextFieldProxyHostKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextFieldProxyHostKeyPressed
        jTextFieldURLKeyPressed(evt);
    }//GEN-LAST:event_jTextFieldProxyHostKeyPressed

    private void _jTextFieldProxyUsernameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event__jTextFieldProxyUsernameKeyPressed
        jTextFieldURLKeyPressed(evt);
    }//GEN-LAST:event__jTextFieldProxyUsernameKeyPressed

    private void jTextFieldProxyPortKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextFieldProxyPortKeyPressed
        jTextFieldURLKeyPressed(evt);
    }//GEN-LAST:event_jTextFieldProxyPortKeyPressed

    private void _jPasswordProxyPasswordKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event__jPasswordProxyPasswordKeyPressed
        jTextFieldURLKeyPressed(evt);
    }//GEN-LAST:event__jPasswordProxyPasswordKeyPressed

    private void jPanelButtonProxyKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jPanelButtonProxyKeyTyped
        jPanelButtonProxyMousePressed(null);
    }//GEN-LAST:event_jPanelButtonProxyKeyTyped

    private void jPanelButtonProxyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelButtonProxyMousePressed
        jPanelProxy.setVisible(!jPanelProxy.isVisible());
        revalidate();
        pack();
    }//GEN-LAST:event_jPanelButtonProxyMousePressed

    private void jPanelButtonGeneralMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelButtonGeneralMousePressed
        jPanelGeneral.setVisible(!jPanelGeneral.isVisible());
        revalidate();
        pack();
    }//GEN-LAST:event_jPanelButtonGeneralMousePressed

    private void jPanelButtonGeneralKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jPanelButtonGeneralKeyTyped
        jPanelButtonGeneralMousePressed(null);
    }//GEN-LAST:event_jPanelButtonGeneralKeyTyped

    private void jPanelButtonWebDAVMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelButtonWebDAVMousePressed
        jPanelWebDAV.setVisible(!jPanelWebDAV.isVisible());
        revalidate();
        pack();
    }//GEN-LAST:event_jPanelButtonWebDAVMousePressed

    private void jPanelButtonWebDAVKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jPanelButtonWebDAVKeyTyped
        jPanelButtonWebDAVMousePressed(null);
    }//GEN-LAST:event_jPanelButtonWebDAVKeyTyped

    private void jButtonWebDAVScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonWebDAVScanActionPerformed

        try {
            jButtonWebDAVScan.setVisible(false);
            jButtonWebDAVStop.setVisible(true);
            _lastScanUri = new URI(jTextFieldWebDAVURL.getText().trim());
            ReverseProxyConfiguration reverseProxyConfiguration = getConfig(_lastScanUri);
            _fullDefaultListModel.removeAllElements();
            _filteredDefaultListModel.removeAllElements();
            _webDAVScanner = new WebDAVScanner(_fullDefaultListModel, reverseProxyConfiguration);
            _webDAVScanner.start();
        }
        catch (Exception e) {
            jButtonWebDAVScan.setVisible(true);
            jButtonWebDAVStop.setVisible(false);
            _webDAVScanner = null;
            new JDialogException(e).setVisible(true);
        }

    }//GEN-LAST:event_jButtonWebDAVScanActionPerformed

    private void jTextFieldWebDAVURLFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldWebDAVURLFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldWebDAVURLFocusGained

    private void jTextFieldWebDAVFilterFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextFieldWebDAVFilterFocusGained
        ((JTextField) evt.getSource()).selectAll();
    }//GEN-LAST:event_jTextFieldWebDAVFilterFocusGained

    private void jButtonWebDAVStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonWebDAVStopActionPerformed
        if (null != _webDAVScanner) {
            _webDAVScanner.kill();
        }
        else {
            jButtonWebDAVScan.setVisible(true);
            jButtonWebDAVStop.setVisible(false);
        }
    }//GEN-LAST:event_jButtonWebDAVStopActionPerformed

    private void jListWebDAVResourcesValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListWebDAVResourcesValueChanged
        if (null != jListWebDAVResources.getSelectedValue()) {
            jTextFieldURL.setText(jListWebDAVResources.getSelectedValue().toString());
        }
    }//GEN-LAST:event_jListWebDAVResourcesValueChanged

    private void jListWebDAVResourcesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListWebDAVResourcesMouseClicked
        if (evt.getClickCount() == 2) {
            jButtonPlayActionPerformed(null);
        }
    }//GEN-LAST:event_jListWebDAVResourcesMouseClicked
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPasswordField _jPasswordProxyPassword;
    private javax.swing.JTextField _jTextFieldProxyUsername;
    private javax.swing.Box.Filler filler1;
    private javax.swing.Box.Filler filler2;
    private javax.swing.Box.Filler filler3;
    private javax.swing.Box.Filler filler4;
    private javax.swing.Box.Filler filler5;
    private javax.swing.JButton jButtonBrowse;
    private javax.swing.JButton jButtonPlay;
    private javax.swing.JButton jButtonWebDAVScan;
    private javax.swing.JButton jButtonWebDAVStop;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JList jListWebDAVResources;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel4;
    private gp.vlc.rp.gui.JPanelButton jPanelButtonGeneral;
    private gp.vlc.rp.gui.JPanelButton jPanelButtonProxy;
    private gp.vlc.rp.gui.JPanelButton jPanelButtonWebDAV;
    private javax.swing.JPanel jPanelGeneral;
    private javax.swing.JPanel jPanelProxy;
    private javax.swing.JPanel jPanelWebDAV;
    private javax.swing.JPasswordField jPasswordPassword;
    private javax.swing.JScrollPane jScrollPaneWebDAVResources;
    private javax.swing.JTextField jTextFieldProxyHost;
    private javax.swing.JTextField jTextFieldProxyPort;
    private javax.swing.JTextField jTextFieldURL;
    private javax.swing.JTextField jTextFieldUsername;
    private javax.swing.JTextField jTextFieldVLC;
    private javax.swing.JTextField jTextFieldWebDAVFilter;
    private javax.swing.JTextField jTextFieldWebDAVURL;
    // End of variables declaration//GEN-END:variables

    private class Consumer extends Thread {

        private InputStream _inputStream;

        private Consumer(InputStream inputStream) {
            _inputStream = inputStream;
        }

        @Override
        public void run() {
            try {
                byte[] buffer = new byte[2048];
                int len = 0;
                while (len != -1) {
                    len = _inputStream.read(buffer);
                }
            }
            catch (Exception e) {
                // nothing to do
            }
        }
    }

    private class WebDAVScanner extends Thread {
        private DefaultHttpClient _defaultHttpClient;
        private DefaultListModel _defaultListModel;
        private ReverseProxyConfiguration _reverseProxyConfiguration;
        private SardineImpl _sardineImpl;
        private Semaphore _semaphore;
        private int running;
        
        public WebDAVScanner(DefaultListModel defaultListModel, ReverseProxyConfiguration reverseProxyConfiguration) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {
            running = 0;
            _semaphore = new Semaphore(0);
            _reverseProxyConfiguration = reverseProxyConfiguration;
            _defaultListModel = defaultListModel;
            _defaultHttpClient = MyFactory.createHttpClient(_reverseProxyConfiguration);
            _sardineImpl = new SardineImpl(_defaultHttpClient, _reverseProxyConfiguration.getCredentials().getUserName(), _reverseProxyConfiguration.getCredentials().getPassword());
        }
        
        private synchronized void started(){
            running++;
        }
        
        private synchronized void ended(){
            running--;
            if(running == 0){
                _semaphore.release();
            }
        }
        
        @Override
        public void run() {
            try {
                started();
                listAndAddFilesAndRecurseOnDirectories(_reverseProxyConfiguration.getURI());
            }
            catch (Exception e) {
                ended();
                new JDialogException(e).setVisible(true);
            }
            
            try {
                _semaphore.acquire();
            }
            catch (Exception e) {
                new JDialogException(e).setVisible(true);
            }
            
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    jButtonWebDAVScan.setVisible(true);
                    jButtonWebDAVStop.setVisible(false);
                    _webDAVScanner = null;
                }
            });
        }

        public void kill() {
            _defaultHttpClient.getConnectionManager().shutdown();
        }

        private void listAndAddFilesAndRecurseOnDirectories(final URI uri) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {
            //SardineImpl _sardineImpl;
            final List<DavResource> list = _sardineImpl.getResources(uri.toString());
            // add files to model

            SwingUtilities.invokeLater(
                    new Runnable() {
                        public void run() {
                            for (DavResource davResource : list) {
                                if (!davResource.isDirectory()) {
                                    _defaultListModel.addElement(uri.resolve(davResource.getHref()));
                                }
                            }
                        }
                    });
            // recurse on directories
            for (final DavResource davResource : list) {
                if (davResource.isDirectory() && !davResource.getHref().getPath().equalsIgnoreCase(uri.getPath())) {
                    started();
                    new Thread() {
                        public void run() {
                            try {
                                listAndAddFilesAndRecurseOnDirectories(uri.resolve(davResource.getHref()));
                            }
                            catch (Exception e) {
                                ended();
                                e.printStackTrace();
                            }
                        }
                    }.start();

                }
            }
            ended();
        }
    }
}
